package cc.rengu.igas.mcps.core.service.trans.cardpay;

import cc.rengu.igas.channel.cups.common.constant.CupsConfigConstant;
import cc.rengu.igas.channel.cups.facade.bean.CupsTermInfo;
import cc.rengu.igas.channel.cups.facade.bean.OrigTxnInfo;
import cc.rengu.igas.channel.cups.facade.request.PreAuthFinishRequest;
import cc.rengu.igas.channel.cups.facade.response.PreAuthFinishResponse;
import cc.rengu.igas.mcps.common.constant.McpsParamConstant;
import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.McpsAcctTypeEnum;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.model.AcctAndFeeType;
import cc.rengu.igas.mcps.core.model.PosTransInfo;
import cc.rengu.igas.mcps.core.realize.EsbRealSttlePaymentService;
import cc.rengu.igas.mcps.core.realize.PosParamDealService;
import cc.rengu.igas.mcps.core.realize.impl.EsbRealSttlePaymentServiceImpl;
import cc.rengu.igas.mcps.core.realize.impl.PosParamDealServiceImpl;
import cc.rengu.igas.mcps.core.service.base.AuthService;
import cc.rengu.igas.mcps.facade.request.PosCardAuthCompRequest;
import cc.rengu.igas.mcps.facade.response.PosCardAuthCompResponse;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntAcctInfo;
import cc.rengu.igas.share.core.model.MchntFeeInfo;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.MchntTermInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.smps.facade.result.Result;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * 银行卡预授权完成
 * create by zhangbin on 2020/03/27
 */
public class PosCardPreAuthCompService extends AuthService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        PosCardAuthCompRequest posCardAuthCompReq = new PosCardAuthCompRequest();
        ConvertUtil.convertOutput(posCardAuthCompReq);
        return posCardAuthCompReq;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        BizResponse bizResponse = new BizResponse();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        PosCardAuthCompRequest posCardAuthCompRequest = (PosCardAuthCompRequest) request;
        PosCardAuthCompResponse posCardAuthCompResponse = new PosCardAuthCompResponse();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String newPin = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.PIN_DATA);
        // 从内部树获取信息
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        String refNo = posParamDealService.getRefNo();
        OrderService orderService = new OrderServiceImpl();
        /*获取账户类型与费率类型*/
        AcctAndFeeType acctAndFeeType = (AcctAndFeeType) xmlTreeUtil.getXmlTreeObjectValue(McpsTreeNodeConstant.ACCT_AND_FEE_TYPE, AcctAndFeeType.class);
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, posCardAuthCompRequest.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("查询商户基本信息失败<{}>", posCardAuthCompRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*获取原商户订单*/
        MchntOrderInfo origMchntOrderInfo = (MchntOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO);
        //获取原用户订单
        UserOrderInfo origUserOrderInfo = (UserOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO);
        /*获取原支付订单号*/
        PayOrderInfo origPayOrderInfo = (PayOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO);
        /*初始化用户订单*/
        UserOrderInfo userOrderInfoAuthCom = initOrderInfoUser(posCardAuthCompRequest, origUserOrderInfo);
        /*初始化商户订单*/
        MchntOrderInfo mchntOrderInfoAuthCom = initOrderInfoMchnt(posCardAuthCompRequest, userOrderInfoAuthCom, acctAndFeeType);
        /*登記用户、商户订单*/
        List<MchntOrderInfo> listMchntOrderInfo = new ArrayList<>();
        listMchntOrderInfo.add(mchntOrderInfoAuthCom);
        if (!orderService.registerOrderInfo(userOrderInfoAuthCom, listMchntOrderInfo, null)) {
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        } else {
            rglog.info("订单创建成功");
        }
        /*获取卡号*/
        String cardNo = posCardAuthCompRequest.getPayAcctNo();
        //获取卡BIN信息并判断是否支持此类卡的渠道交易
        //非特殊费率商户 计算手续费
        if (!"0".equals(mchntOrderInfoAuthCom.getFeeInputMode())) {
            /*调用手续费计算接口*/
            rglog.debug("手续费计算数据instId:<{}>,mchntNo<{}>,amount:<{}>,bizprodCode<{}>,feeType:<{}>,stageCode:<{}>,stageNum:<{}>", instId, posCardAuthCompRequest.getMchntNo(), mchntOrderInfoAuthCom.getRealSettleAmt(), txnInfo.getSrcTxnAuthCfg().getBizProdCode(), acctAndFeeType.getFeeType(), null, null);
            boolean calcResult = mchntService.calcMchntFee(mchntOrderInfoAuthCom, acctAndFeeType.getFeeType());
            //mod by lizhangtao 由于商户费率信息表中不同的产品存以下三种组合：全特殊费率，全非特殊费率，特殊和非特殊都存在；
            // 且计算手续费时只要存在特殊费率（不管是不是当前产品的）都不实时计算手续费
            // 失败：
            //   1. 返回为空 ||
            //   2. 该商户计算手续费应答中认为非特殊费率商户（全都是非特殊费率），但是没有手续费
            // 成功：(除以上失败)
            //   返回对象非空 && ((返回的FeeInputMode为0 && 无手续费) || (返回的FeeInputMode为非0 && 有手续费))
            if (!calcResult ||
                    (!"0".equals(mchntOrderInfoAuthCom.getFeeInputMode()) &&
                            null == mchntOrderInfoAuthCom.getMchntFee())) {
                updateFailOrderInfo(posCardAuthCompRequest, RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespDesc(), userOrderInfoAuthCom, mchntOrderInfoAuthCom, null, false);
                rglog.error("计算商户手续费失败");
                throw new BizException(RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespCode(), RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespDesc());
            }
            if ("0".equals(mchntOrderInfoAuthCom.getFeeInputMode())) {
                rglog.debug("由于存在了其他产品为特殊计费，因此该商户<{}>被认为是特殊费率商户不计算手续费！！", mchntOrderInfoAuthCom.getMchntNo());
                mchntOrderInfoAuthCom.setMchntSettleAmt(mchntOrderInfoAuthCom.getOrderAmt());
            }
        } else {
            rglog.debug("商户<{}>被认为是特殊费率商户不计算手续费！！", mchntOrderInfoAuthCom.getMchntNo());
            mchntOrderInfoAuthCom.setMchntSettleAmt(mchntOrderInfoAuthCom.getOrderAmt());
        }
        /*判断是否商户实时清算方式*/
        judeRealTimClearWay(posCardAuthCompRequest, mchntInfo, mchntOrderInfoAuthCom, acctAndFeeType);
        PayOrderInfo oriPayOrderInfo = (PayOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO);
        /*创建登记支付订单*/
        PayOrderInfo payOrderInfoESB = InitPayOrderInfoPreAuthCom(userOrderInfoAuthCom, posCardAuthCompRequest, acctAndFeeType.getAcctType(), oriPayOrderInfo, refNo);
        if (!orderService.registerOrderInfo(null, null, payOrderInfoESB)) {
            updateFailOrderInfo(posCardAuthCompRequest, RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc(), userOrderInfoAuthCom, mchntOrderInfoAuthCom, null, true);
            rglog.error("支付订单创建失败！！");
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }
        //本行贷记卡调用银数接口
        if (McpsAcctTypeEnum.OWN_CREDIT.getAcctType().equals(acctAndFeeType.getAcctType())) {
            updcPreAuthComp(posCardAuthCompRequest, origUserOrderInfo, origMchntOrderInfo, origPayOrderInfo, newPin, userOrderInfoAuthCom, mchntOrderInfoAuthCom, payOrderInfoESB);
        }
        //他行卡
        if (McpsAcctTypeEnum.OTHER_DEBIT.getAcctType().equals(acctAndFeeType.getAcctType()) || McpsAcctTypeEnum.OTHER_CREDIT.getAcctType().equals(acctAndFeeType.getAcctType())) {
            othersPreAuthCompe(posCardAuthCompRequest, origUserOrderInfo, origMchntOrderInfo, origPayOrderInfo, newPin, userOrderInfoAuthCom, mchntOrderInfoAuthCom, payOrderInfoESB, acctAndFeeType.getAcctType(), posCardAuthCompResponse, refNo);
        }
        /*特殊费率商户交易成功后调用微信进行消息推送*/
        if ("0".equals(mchntOrderInfoAuthCom.getFeeInputMode()) && TransStatusEnum.TRANS_SUCC.getStatus().equals(payOrderInfoESB.getTransStatus()) && BizStatusEnum.FINISH.getStatus().equals(payOrderInfoESB.getBizStatus())) {
            GlobalTransUtil.setCacheValue(TransCacheConstant.USER_ORDER_INFO, userOrderInfoAuthCom);
            int iReturnCode = asynnotify.transactionNotice("MchntTransNoticeService", 1, 0, 0);
            if (0 != iReturnCode) {
                rglog.error("提交交易结果异步通知给商户失败!");
            }
        }
        /*重组返回报文*/
        ConvertUtil.convertOutput(posCardAuthCompResponse);
        cc.rengu.igas.mcps.facade.base.Header header = new cc.rengu.igas.mcps.facade.base.Header();
        BeanUtil.beanCopy(posCardAuthCompRequest.getHeader(), header);
        posCardAuthCompResponse.setHeader(header);
        //TODO 待修改
        posCardAuthCompResponse.setPayAcctNo(posCardAuthCompRequest.getPayAcctNo());
        posCardAuthCompResponse.setPayId(sysSeqNum);
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(payOrderInfoESB.getRespCode());
        bizResponse.setRespDesc(payOrderInfoESB.getRespDesc());
        bizResponse.setResult(posCardAuthCompResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        PosCardAuthCompResponse posCardAuthCompRsp = (PosCardAuthCompResponse) bizResponse.getResult();
        posCardAuthCompRsp.setRespCode(bizResponse.getRespCode());
        posCardAuthCompRsp.setRespDesc(bizResponse.getRespDesc());
        ConvertUtil.convertInput(posCardAuthCompRsp);
    }

    /**
     * 初始化支付订单表
     *
     * @param posCardAuthCompRequest 请求信息
     * @throws Exception 异常
     */
    private PayOrderInfo InitPayOrderInfoPreAuthCom(UserOrderInfo userOrderInfo, PosCardAuthCompRequest posCardAuthCompRequest, String acctType, PayOrderInfo oriPayOrderInfo, String refNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /**/
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /* 登记支付订单信息 */
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String txnNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_NUM);
        String bizType = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.BIZ_TYPE);
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        payOrderInfo.setSysSeqNum(sysSeqNum);
        payOrderInfo.setMchntOrderId(sysSeqNum);
        payOrderInfo.setInstId(instId);
        payOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
        payOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
        payOrderInfo.setTxnNum(txnNum);
        payOrderInfo.setBizType(bizType);
        /*设置通到序号*/
        String strIndex = xmlTreeUtil.getXmlTreeStringValue("currentDstCallIndex");
        Integer acctCallIndex = new Integer((StringUtil.isEmptyOrNull(strIndex)) ? "0" : strIndex);
        String dstAcctCallIndex = Integer.toString(acctCallIndex + 1);
        payOrderInfo.setDstCallIndex(acctCallIndex.toString());
        xmlTreeUtil.setXmlTreeStringValue("currentDstCallIndex", dstAcctCallIndex);
        //payOrderInfo.setMchntOrderId(posCardAuthCompRequest.getOrderId());
        payOrderInfo.setOrderCcy(AppParamConstant.DEFAULT_ORDER_CCY);
        payOrderInfo.setOrderAmt(userOrderInfo.getOrderAmt());
        if (null != userOrderInfo.getRealPayAmt()) {
            payOrderInfo.setRealPayAmt(userOrderInfo.getRealPayAmt());
        } else {
            payOrderInfo.setRealPayAmt(userOrderInfo.getOrderAmt());
        }
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        payOrderInfo.setMchntNo(posCardAuthCompRequest.getMchntNo());
        payOrderInfo.setChannelOrderId(sysSeqNum);
        /*通道标示*/
        payOrderInfo.setMsgDstId(ChannelEnum.CUPS.getChannelType());
        if (McpsAcctTypeEnum.OWN_CREDIT.getAcctType().equals(acctType)) {
            /*支付方式*/
            payOrderInfo.setPayType(PayTypeEnum.BANK_CARD.getPayType());
            /*对账唯一key*/
            payOrderInfo.setChannelReconKey(payOrderInfo.getChannelOrderId());
            payOrderInfo.setChannelBizType("0000");
            /*通道交易码*/
            payOrderInfo.setDstTxnNum("002600105088C0");
        } else {
            /*支付方式*/
            payOrderInfo.setPayType(PayTypeEnum.OTHER_BANK_CARD.getPayType());
            /*对账唯一key*/
            payOrderInfo.setChannelReconKey(posParamDealService.getCupsReconKey(instId, posCardAuthCompRequest.getMchntNo()));
            /*通道类型*/
            payOrderInfo.setDstChannelType(ChannelEnum.CUPS.getChannelType());
            /*支付方式*/
            payOrderInfo.setPayType(PayTypeEnum.OTHER_BANK_CARD.getPayType());
            ChannelCallCfg channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item -> ChannelEnum.CUPS.getChannelType().equals(item.getCallChannelId())).collect(Collectors.toList()).get(0);
            /*通道交易码*/
            payOrderInfo.setDstTxnNum(channelCallCfgList.getCallChannelTxn());
        }
        payOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        payOrderInfo.setPayerAcctInfo(posCardAuthCompRequest.getPayAcctNo());
        payOrderInfo.setPayerAcctType(oriPayOrderInfo.getPayerAcctType());
        payOrderInfo.setPayeeAcctInfo(oriPayOrderInfo.getPayeeAcctInfo());
        payOrderInfo.setOrigSysSeqNum(oriPayOrderInfo.getSysSeqNum());
        payOrderInfo.setOrigTxnDate(oriPayOrderInfo.getTxnDate());
        PosTransInfo posTransInfo = new PosTransInfo();
        BeanUtil.beanCopy(posCardAuthCompRequest, posTransInfo);
        //预授权完成37域重新生成
        posTransInfo.setRefNo(refNo);
        payOrderInfo.setPayerRemark(org.apache.commons.codec.binary.Base64.encodeBase64String(JSONObject.toJSONString(posTransInfo).getBytes()));
        rglog.debug("通道支付订单：<{}>", JSON.toJSONString(payOrderInfo));
        return payOrderInfo;
    }

    /**
     * 初始化商户订单表
     *
     * @param posCardAuthCompRequest 请求信息
     * @throws Exception 异常
     */
    private MchntOrderInfo initOrderInfoMchnt(PosCardAuthCompRequest posCardAuthCompRequest,
                                              UserOrderInfo userOrderInfo, AcctAndFeeType acctAndFeeType) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(posCardAuthCompRequest.getHeader().getInstId(), posCardAuthCompRequest.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("查询商户基本信息失败<{}>", posCardAuthCompRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        //获取商户结算账户信息
        MchntAcctInfo mchntAcctInfo = getMchntAcctInfo(posCardAuthCompRequest, mchntInfo);
        /*获取商户费率信息*/
        MchntFeeInfo mchntFeeInfo = (MchntFeeInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.MCHNT_FEE_INFO);
        /*内部树复制会把订单状态保存到商户订单信息表*/
        BeanUtil.beanCopy(userOrderInfo, mchntOrderInfo);
        /*设置操作员id*/
        mchntOrderInfo.setUserId(null);
        /*商户手续费收取方式*/
        mchntOrderInfo.setFeeInputMode(mchntFeeInfo.getFeeInputMode());
        /*设置商户订单表中业务产品代码*/
        mchntOrderInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
        /*商户订单号*/
        mchntOrderInfo.setMchntOrderId(sysSeqNum);
        /*收单机构号 */
        mchntOrderInfo.setAcqInstCode(mchntInfo.getSignInstId());
        /*行业类别*/
        mchntOrderInfo.setIndustryType(mchntInfo.getIndustryType());
        /*商户号*/
        mchntOrderInfo.setMchntNo(posCardAuthCompRequest.getMchntNo());
        /*若存在 设置连锁商户门店*/
        if (null != mchntInfo.getChainMchntNo()) {
            mchntOrderInfo.setChainMchntNo(mchntInfo.getChainMchntNo());
        }
        /*商户名称*/
        mchntOrderInfo.setMchntName(mchntInfo.getMchntName());
        /*交易金額*/
        mchntOrderInfo.setOrderAmt(posCardAuthCompRequest.getTransAmt());
        /*终端号*/
        mchntOrderInfo.setTermNo(posCardAuthCompRequest.getTermNo());
        /*交易币种*/
        mchntOrderInfo.setOrderCcy(AppParamConstant.DEFAULT_ORDER_CCY);
        /*实际清算本金金额*/
        mchntOrderInfo.setRealSettleAmt(mchntOrderInfo.getOrderAmt());
        /*实时清算标识*/
        mchntOrderInfo.setRealSettleFlag(mchntInfo.getRealSettleFlag());
        /*设置交易状态*/
        mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        /*设置业务状态*/
        mchntOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        /*创建时间*/
        mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        mchntOrderInfo.setRealSettleFlag(AppParamConstant.NO);
        return mchntOrderInfo;
    }

    /**
     * 初始化用户订单表
     *
     * @param posCardAuthCompRequest 请求信息
     * @throws Exception 异常
     */
    private UserOrderInfo initOrderInfoUser(PosCardAuthCompRequest posCardAuthCompRequest, UserOrderInfo oriUserOrderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /*获取机构号*/
        String instId = posCardAuthCompRequest.getHeader().getInstId();
        /*获取交易码*/
        String txnNum = posCardAuthCompRequest.getHeader().getTxnNum();
        /*获取业务细分*/
        String bizType = posCardAuthCompRequest.getHeader().getBizType();
        /*获取源系统标识*/
        String msgSrcId = posCardAuthCompRequest.getHeader().getSrcSysId();
        userOrderInfo.setUserOrderId(sysSeqNum);
        userOrderInfo.setMchntOrderId(sysSeqNum);
        userOrderInfo.setInstId(instId);
        userOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
        userOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
        userOrderInfo.setTxnNum(txnNum);
        userOrderInfo.setBizType(bizType);
        userOrderInfo.setMsgSrcId(msgSrcId);

        userOrderInfo.setTransChannelId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_CHANNEL_ID));
        //userOrderInfo.setMchntOrderId(posCardAuthCompRequest.getOrderId());
        //userOrderInfo.setOrderDesc(posCardAuthCompRequest.getOrderDescription());
        userOrderInfo.setFrontSeqNum(posCardAuthCompRequest.getHeader().getTraceNo());
        userOrderInfo.setSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        userOrderInfo.setOrderCreateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
        userOrderInfo.setOrderExpiryTime(DateUtil.getDateByTimeStamp(System.currentTimeMillis() + 5 * 60 * 1000, "yyyyMMddHHmmss"));
        userOrderInfo.setOrderExpiryTime(DateUtil.getDateByTimeStamp(System.currentTimeMillis() + 5 * 60 * 1000, "yyyyMMddHHmmss"));
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setOrderAmt(posCardAuthCompRequest.getTransAmt());
        userOrderInfo.setUserId(posCardAuthCompRequest.getPayAcctNo());
        userOrderInfo.setOrigTxnDate(oriUserOrderInfo.getTxnDate());
        userOrderInfo.setOrigSysSeqNum(oriUserOrderInfo.getSysSeqNum());
        userOrderInfo.setUserId(posCardAuthCompRequest.getPayAcctNo());
        return userOrderInfo;
    }

    /*本行贷记卡 通道调用*/
    private void updcPreAuthComp(PosCardAuthCompRequest posCardAuthCompRequest, UserOrderInfo origUserOrderInfo,
                                 MchntOrderInfo origMchntOrderInfo, PayOrderInfo origPayOrderInfo, String newPin, UserOrderInfo userOrderInfoPreAuthComp,
                                 MchntOrderInfo mchntOrderInfoPreAuthComp, PayOrderInfo payOrderInfoPreAuthComp) throws Exception {
        /*设置dubbo服务*/
        DubboService dubboService = new DubboServiceImpl();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*获取商户号*/
        String mchntNo = posCardAuthCompRequest.getMchntNo();
        /*获取终端号*/
        String termNo = posCardAuthCompRequest.getTermNo();
        /*获取机构号*/
        String instId = posCardAuthCompRequest.getHeader().getInstId();
        /*获取系统流水号*/
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /*获取商户基本信息*/
//       /*校验上送密码是否正确*/
        checkPin(posCardAuthCompRequest, newPin, userOrderInfoPreAuthComp, mchntOrderInfoPreAuthComp, payOrderInfoPreAuthComp);
        /*设置银数预授权完成请求报文*/
        // TODO 银数预授权完成
        // （1） 调用失败，更新订单状态为失败，调用营销冲正comboDealService.cancelComboPayment
        // （2） 调用超时，更新订单为超时
        // （3） 调用成功，更新三张订单表状态为成功，更新原订单表为预授权完成
        //          是否实时清算调用esbRealSttlePaymentService.esbRealTimeClear/esbRealSttlePaymentService.esbRealSettlePayment
        //          特殊费率商户虚拟账户单笔记账acctDealService.virtAcctSingleAdjust
        //          更新商户限额、终端限额、交易限额及笔数mchntService.addTxnLimitStatis

    }

    /*他行卡 通道调用*/
    private void othersPreAuthCompe(PosCardAuthCompRequest posCardAuthCompRequest, UserOrderInfo origUserOrderInfo,
                                    MchntOrderInfo origMchntOrderInfo, PayOrderInfo origPayOrderInfo, String newPin, UserOrderInfo userOrderInfoPreAuthComp,
                                    MchntOrderInfo mchntOrderInfoPreAuthComp, PayOrderInfo payOrderInfoPreAuthComp, String acctType,
                                    PosCardAuthCompResponse posCardAuthCompResponse, String refNo) throws Exception {
        /*设置dubbo服务*/
        DubboService dubboService = new DubboServiceImpl();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*获取商户号*/
        String mchntNo = posCardAuthCompRequest.getMchntNo();
        /*获取终端号*/
        String termNo = posCardAuthCompRequest.getTermNo();
        /*获取机构号*/
        String instId = posCardAuthCompRequest.getHeader().getInstId();
        /*获取系统流水号*/
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        /*原交易信息*/
        OrigTxnInfo origTxnInfo = new OrigTxnInfo();
        origTxnInfo.setOriTraceNo(origPayOrderInfo.getChannelOrderId());
        origTxnInfo.setOriTxnDate(origPayOrderInfo.getTxnDate());
        origTxnInfo.setOriTransDateTime(origPayOrderInfo.getTxnDate().substring(4, 8) + origPayOrderInfo.getTxnTime());
        origTxnInfo.setOriCupsTraceNo(origPayOrderInfo.getSysSeqNum().substring(sysNum.length() - 6, sysNum.length()));

        /*准备请求报文*/
        PreAuthFinishRequest preAuthFinishRequest = new PreAuthFinishRequest();
        /*设置Header*/
        cc.rengu.igas.channel.cups.facade.base.Header header = new cc.rengu.igas.channel.cups.facade.base.Header();
        BeanUtil.beanCopy(posCardAuthCompRequest.getHeader(), header);
        header.setVersion("1.0.0");
        header.setTxnNum(payOrderInfoPreAuthComp.getDstTxnNum());
        header.setTraceNo(payOrderInfoPreAuthComp.getChannelOrderId());
        preAuthFinishRequest.setHeader(header);
        preAuthFinishRequest.setOrigTxnInfo(origTxnInfo);
        preAuthFinishRequest.setCupsTraceNo(sysNum.substring(sysNum.length() - 6));
        preAuthFinishRequest.setTransDateTime(payOrderInfoPreAuthComp.getTxnDate().substring(4, 8) + payOrderInfoPreAuthComp.getTxnTime());
        preAuthFinishRequest.setCupsMchntNo(mchntInfo.getCupsMchntNo());
        preAuthFinishRequest.setMchntNo(preAuthFinishRequest.getMchntNo());
        preAuthFinishRequest.setTermNo(termNo);
        preAuthFinishRequest.setMchntShortName(mchntInfo.getMchntSimpleName());
        preAuthFinishRequest.setMchntType(mchntInfo.getIndustryType());
        String acqInstCode = posParamDealService.genCupsAcqInstCode(instId, posCardAuthCompRequest.getMchntNo());
        String fwdInstCode = XmlConfigUtil.getXmlConfigCacheKeyValue(CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_FWD_INS_CODE);
        preAuthFinishRequest.setCupsInstCode(acqInstCode);
        preAuthFinishRequest.setFwdInstCode(fwdInstCode);
        preAuthFinishRequest.setOrderAmt(payOrderInfoPreAuthComp.getRealPayAmt());
        preAuthFinishRequest.setOrderCcy(McpsParamConstant.INNER_DEFAULT_ORDERCCY);
        preAuthFinishRequest.setPayAcctNo(payOrderInfoPreAuthComp.getPayerAcctInfo());
        //TODO 待修改
        preAuthFinishRequest.setAuthCode(posCardAuthCompRequest.getTransAuthCode());
        payOrderInfoPreAuthComp.setTxnAuthCode(posCardAuthCompRequest.getTransAuthCode());
        preAuthFinishRequest.setTrack2Data(posCardAuthCompRequest.getTrack2Data());
        preAuthFinishRequest.setTrack3Data(posCardAuthCompRequest.getTrack3Data());
        preAuthFinishRequest.setReferenceNo(refNo);
        preAuthFinishRequest.setCardExpireDate(posCardAuthCompRequest.getCardexpireDate());
        preAuthFinishRequest.setEntryMode(posCardAuthCompRequest.getEntryMode());
        preAuthFinishRequest.setCardSeqNo(posCardAuthCompRequest.getCardSeqNo());
        preAuthFinishRequest.setIcData(posCardAuthCompRequest.getIcData());
        preAuthFinishRequest.setIcConCode(posCardAuthCompRequest.getIcConCode());
        //preAuthFinishRequest.setIcDataLength(posCardAuthCompRequest.getIcDataLengt);
        //preAuthFinishRequest.setPinCapCode(posCardAuthCompRequest.getPinTrcode());
        preAuthFinishRequest.setPinData(newPin);

        CupsTermInfo cupsTermInfo = new CupsTermInfo();
        BeanUtil.beanCopy(posCardAuthCompRequest.getTermInfo(), cupsTermInfo);
        if (StringUtil.isEmptyOrNull(cupsTermInfo.getDeviceType())) {
            /*获取终端信息*/
            MchntTermInfo mchntTermInfo = mchntService.getMchntTermInfo(instId, mchntNo, posCardAuthCompRequest.getTermNo());
            cupsTermInfo.setDeviceType(mchntTermInfo.getTermType());
        }
        preAuthFinishRequest.setTermInfo(cupsTermInfo);
        preAuthFinishRequest.setTermRead(posCardAuthCompRequest.getTermRead());
        //consumeRequest.setAcqReserved();
        /*打印报文*/
        rglog.info("银联请求报文preAuthFinishRequest：<{}>", JSON.toJSONString(preAuthFinishRequest));
        cc.rengu.igas.channel.cups.facade.result.Result<PreAuthFinishResponse> preAuthFinishResponse = new cc.rengu.igas.channel.cups.facade.result.Result();
        rglog.debug("dubbo调用预授完成结果：{}", JSON.toJSONString(preAuthFinishResponse));
        preAuthFinishResponse = (cc.rengu.igas.channel.cups.facade.result.Result) dubboService.callDubboService("cupsPayService", "preAuthFinish", preAuthFinishRequest);
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
        /*初始化订单服务*/
        OrderService orderService = new OrderServiceImpl();
        //调用成功处理
        if (preAuthFinishResponse.isSuccess() && McpsParamConstant.DUBBO_SUCCESS.equals(preAuthFinishResponse.getResult().getRespCode())) {
            /*更新三张订单表*/
            payOrderInfoPreAuthComp.setRespCode(preAuthFinishResponse.getResult().getRespCode());
            payOrderInfoPreAuthComp.setRespDesc(preAuthFinishResponse.getResult().getRespDesc());
            payOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            payOrderInfoPreAuthComp.setBizStatus(BizStatusEnum.FINISH.getStatus());
            /*设置通道清算日期*/
            payOrderInfoPreAuthComp.setSettleDate(preAuthFinishResponse.getResult().getSettleDate());
            payOrderInfoPreAuthComp.setTxnAuthCode(origPayOrderInfo.getTxnAuthCode());
            mchntOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfoPreAuthComp.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            userOrderInfoPreAuthComp.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userOrderInfoPreAuthComp.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            mchntOrderInfoList.add(mchntOrderInfoPreAuthComp);
            /*更新*/
            if (!orderService.updateOrderInfo(userOrderInfoPreAuthComp, mchntOrderInfoList, payOrderInfoPreAuthComp)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
            /*更新原交易三张订单 状态为已完成*/
            origMchntOrderInfo.setBizStatus(BizStatusEnum.AUTH_COMPLETE.getStatus());
            origPayOrderInfo.setBizStatus(BizStatusEnum.AUTH_COMPLETE.getStatus());
            origUserOrderInfo.setBizStatus(BizStatusEnum.AUTH_COMPLETE.getStatus());
            List<MchntOrderInfo> origListMchntOrderInfo = new ArrayList<>();
            origListMchntOrderInfo.add(origMchntOrderInfo);
            /*更新*/
            if (!orderService.updateOrderInfo(origUserOrderInfo, origListMchntOrderInfo, origPayOrderInfo)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
            /*预授权完成的商户订单表插入内部树中*/
            xmlTreeUtil.setXmlTreeObjectValue(McpsTreeNodeConstant.MCHNT_ORDER_INFO, mchntOrderInfoPreAuthComp);
            /*判断是否实时清算*/
            EsbRealSttlePaymentService esbRealSttlePaymentService = new EsbRealSttlePaymentServiceImpl();
            if (AppParamConstant.YES.equals(mchntOrderInfoPreAuthComp.getRealSettleFlag())) {
                if ("00".equals(mchntOrderInfoPreAuthComp.getRealSettleType())) {
                    esbRealSttlePaymentService.esbRealTimeClear(mchntOrderInfoPreAuthComp, payOrderInfoPreAuthComp, posCardAuthCompRequest.getHeader());
                } else {
                    esbRealSttlePaymentService.esbRealSettlePayment(mchntOrderInfoPreAuthComp, payOrderInfoPreAuthComp, posCardAuthCompRequest.getHeader());
                }
            }
            //更新商户限额、终端限额、交易限额及笔数
            mchntService.updateMchntTransLimit(mchntOrderInfoPreAuthComp);
        }
        //调用超时处理
        else if (preAuthFinishResponse.isSuccess() && (McpsParamConstant.DUBBO_OVERTIME.equals(preAuthFinishResponse.getResult().getRespCode()) || McpsParamConstant.COMMUNICATION_OVERTIME.equals(preAuthFinishResponse.getResult().getRespCode()))) {
            payOrderInfoPreAuthComp.setRespCode(preAuthFinishResponse.getResult().getRespCode());
            payOrderInfoPreAuthComp.setRespDesc(preAuthFinishResponse.getResult().getRespDesc());
            payOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            mchntOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            userOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            mchntOrderInfoList.add(mchntOrderInfoPreAuthComp);
            /*更新*/
            if (!orderService.updateOrderInfo(userOrderInfoPreAuthComp, mchntOrderInfoList, payOrderInfoPreAuthComp)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
        } else {
            payOrderInfoPreAuthComp.setRespCode(preAuthFinishResponse.getResult().getRespCode());
            payOrderInfoPreAuthComp.setRespDesc(preAuthFinishResponse.getResult().getRespDesc());
            payOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfoPreAuthComp.setBizStatus(BizStatusEnum.FAILED.getStatus());
            mchntOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            mchntOrderInfoPreAuthComp.setBizStatus(BizStatusEnum.FAILED.getStatus());
            userOrderInfoPreAuthComp.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userOrderInfoPreAuthComp.setBizStatus(BizStatusEnum.FAILED.getStatus());
            userOrderInfoPreAuthComp.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            mchntOrderInfoList.add(mchntOrderInfoPreAuthComp);
            /*更新*/
            if (!orderService.updateOrderInfo(userOrderInfoPreAuthComp, mchntOrderInfoList, payOrderInfoPreAuthComp)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
        }

        /*设置返回码 返回信息*/
        if (null == preAuthFinishResponse || !preAuthFinishResponse.isSuccess()) {
            posCardAuthCompResponse.setRespCode(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
            posCardAuthCompResponse.setRespDesc(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
        } else {
            posCardAuthCompResponse.setRespCode(preAuthFinishResponse.getResult().getRespCode());
            posCardAuthCompResponse.setRespDesc(preAuthFinishResponse.getResult().getRespDesc());
            posCardAuthCompResponse.setPayId(sysNum);
            posCardAuthCompResponse.setSettleDate(preAuthFinishResponse.getResult().getSettleDate());
            posCardAuthCompResponse.setReferenceNo(preAuthFinishRequest.getReferenceNo());
            //收单机构
            posCardAuthCompResponse.setAcqInstCode(preAuthFinishRequest.getCupsInstCode());
            //发卡机构
            posCardAuthCompResponse.setPayAcctIssCode(preAuthFinishResponse.getResult().getRcvInstCode());
            posCardAuthCompResponse.setTxnDate(preAuthFinishRequest.getHeader().getTransDate());
            posCardAuthCompResponse.setTxnTime(preAuthFinishRequest.getHeader().getTransTime());
        }

    }

    /*判断上送密码是否正确*/
    private void checkPin(PosCardAuthCompRequest posCardAuthCompRequest, String newPin, UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo, PayOrderInfo payOrderInfo) throws Exception {
        /*设置dubbo服务*/
        DubboService dubboService = new DubboServiceImpl();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*获取商户号*/
        String mchntNo = posCardAuthCompRequest.getMchntNo();
        /*获取终端号*/
        String termNo = posCardAuthCompRequest.getTermNo();
        /*获取机构号*/
        String instId = posCardAuthCompRequest.getHeader().getInstId();
        /*获取系统流水号*/
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /*获取商户基本信息*/
        /*设置银数预授权完成请求报文*/
        //TODO 本行贷记卡通过卡号查询卡信息
        /*初始化dubbo服务*/
        cc.rengu.igas.smps.facade.result.Result result = new Result();
        OrderService orderService = new OrderServiceImpl();
        if (result.isSuccess() && "".equals(McpsParamConstant.DUBBO_SUCCESS)) {
            rglog.info("密码校验成功");
        } else if (result.isSuccess() && "".equals(McpsParamConstant.DUBBO_OVERTIME)) {
            payOrderInfo.setRespDesc("");
            payOrderInfo.setRespCode("");
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            payOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            rglog.error("密码校验超时");
            /*更新*/
            if (!orderService.updateOrderInfo(userOrderInfo, Arrays.asList(mchntOrderInfo), payOrderInfo)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
            throw new BizException(RespCodeEnum.POS_RSP_TIME_OUT.getRespCode(), RespCodeEnum.POS_RSP_TIME_OUT.getRespDesc());
        } else {
            payOrderInfo.setRespDesc(RespCodeEnum.PASS_WORD_CHECK_ERROR.getRespDesc());
            payOrderInfo.setRespCode(RespCodeEnum.PASS_WORD_CHECK_ERROR.getRespCode());
            userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            rglog.info("密码校验失败");
            /*更新*/
            if (!orderService.updateOrderInfo(userOrderInfo, Arrays.asList(mchntOrderInfo), payOrderInfo)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
            throw new BizException(RespCodeEnum.PASS_WORD_CHECK_ERROR.getRespCode(), RespCodeEnum.PASS_WORD_CHECK_ERROR.getRespDesc());
        }
    }

    /*
     * 更新失败订单，并且更新失败原因
     * @param remark 失败原因
     * */
    private void updateFailOrderInfo(PosCardAuthCompRequest posCardAuthCompRequest, String errorInfo, UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo, PayOrderInfo payOrderInfo, boolean cancleFlag) throws Exception {
        /*更新用户订单表和商户订单表，状态为失败，并抛出异常,进行营销撤销
        设置用户订单的信息和状态,设置订单状态：01（订单关闭） 交易状态:2（交易失败） 业务状态：00（处理成功）*/
        /*获取费率信息*/
        userOrderInfo.setOrderStatus(OrderStatusEnum.CLOSE.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        /*设置商户订单状态和信息，设置商户订单状态，交易状态:01(失败) 业务状态：00（处理完成）*/
        mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
        mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        mchntOrderInfo.setRemark3(errorInfo);
        //更新用户订单表和商户订单表状态
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<MchntOrderInfo>();
        mchntOrderInfoList.add(mchntOrderInfo);
        OrderService orderService = new OrderServiceImpl();
        boolean iReturnCode = orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo);
        if (false == iReturnCode) {
            rglog.error("更新订单信息失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }
    }

    /*获取实时入账最小金额*/
    public String getRealTimeClearAmt(String instId) throws Exception {
        String paramType = "MCHNT_SERVICE";
        String paramKey = "D0_ACCOUNTING_MIN_AMT";
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, paramType, paramKey);
        if (null == sysParam) {
            rglog.info("实时入账最小金额未配置,使用默认金额");
            return McpsParamConstant.DEFAULT_REAL_TIME_PAY_MIN_AMT;
        } else {
            return sysParam.getParamValue();
        }
    }

    /*判断是否商户实时清算方式*/
    private void judeRealTimClearWay(PosCardAuthCompRequest posCardAuthCompRequest, MchntInfo mchntInfo, MchntOrderInfo mchntOrderInfo, AcctAndFeeType acctAndFeeType) throws Exception {
        /*获取结算账户信息*/
        MchntAcctInfo mchntAcctInfo = getMchntAcctInfo(posCardAuthCompRequest, mchntInfo);
        /* 获取实时入账最低金额*/
        String minAmt = getRealTimeClearAmt(mchntOrderInfo.getInstId());
        /*判断交易金额是否大于实时入账最低金额*/
        if (AmountUtil.compare(mchntOrderInfo.getRealSettleAmt(), minAmt) != -1) {
            /* 实时清算标识 、结算方式*/
            if ("Y".equals(mchntInfo.getRealSettleFlag()) && (McpsAcctTypeEnum.OWN_DEBIT.getAcctType().equals(acctAndFeeType.getAcctType()) || McpsAcctTypeEnum.OWN_CREDIT.getAcctType().equals(acctAndFeeType.getAcctType()))) {
                mchntOrderInfo.setRealSettleFlag("Y");
                mchntOrderInfo.setRealSettleType("00");
            } else if ("D0".equals(mchntAcctInfo.getSettleType()) && !"Y".equals(mchntInfo.getRealSettleFlag())) {
                mchntOrderInfo.setRealSettleFlag("Y");
                mchntOrderInfo.setRealSettleType("99");
            } else {
                mchntOrderInfo.setRealSettleFlag("N");
            }
        }
    }

    /*获取商户结算账户信息*/
    private MchntAcctInfo getMchntAcctInfo(PosCardAuthCompRequest request, MchntInfo mchntInfo) throws Exception {
        String mchntNo = mchntInfo.getMchntNo();
        /*判断商户是否为独立清算商户*/
        if (!"Y".equals(mchntInfo.getIndependentDataFlag()) && "11".equals(mchntInfo.getMchntType())) {
            mchntNo = mchntInfo.getChainMchntNo();
        }
        MchntService mchntService = new MchntServiceImpl();
        List<MchntAcctInfo> mchntAcctInfoList = mchntService.getMchntAcctInfo(request.getHeader().getInstId(), mchntNo);
        Optional<MchntAcctInfo> mchntAcctInfoOpt = mchntAcctInfoList.stream().filter(item -> item.getFundType().equals("00")).findFirst();
        return mchntAcctInfoOpt.orElse(null);
    }
}
